<?php


namespace App\Http\Controllers\Auth;

use App\Enums\Common\CodeEnum;
use App\Http\Controllers\Common\ApiHelper;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\MiniApp\Application;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;

class AuthController extends Controller
{
    /**
     * @param Request $request
     * @return JsonResponse
     * @throws InvalidArgumentException
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     * @throws TransportExceptionInterface
     * @author  ckg
     * @desc 用户登陆
     */
    public function login(Request $request): JsonResponse
    {

        $param = $request->all();

        //todo  测试开发登录使用
        /*          if (!empty($param['open_id'])) {
                      $check_user = ServiceUser::query()->where(['open_id' => $param['open_id']])->first();
                      if (!$check_user) {
                          return ApiHelper::responseError($param, '用户名or密码错误！', CodeEnum::CODE_CHECK_AUTH);
                      }
                      $token = auth('Api')->login($check_user);
                      return $this->respondWithToken($token, $check_user->tel);
                  }
                  exit();*/

        $dinnerHost = 'https://hospital.kjhhello.cn/api/';
        if (isset($param['code']) && !empty($param['code'])) {
            $config = config('wechat.mini_program.default');
            /*  if ($type == 1) {///服务端
                  $config = config('wechat.work_micro_program.default');
              }*/
            $code = (string)$param['code'];
            $app = new Application($config);
            $utils = $app->getUtils();
            try {
                $data = $utils->codeToSession($code);
            } catch (\Exception $e) {
                return ApiHelper::backDataCheck(false, $e->getMessage());
            }

            $data['unionid'] = $data['unionid'] ?? '';
            if (empty($data['openid'])) {
                Log::info('回调解密信息：', [$data]);
                return ApiHelper::backDataCheck(false, '授权失败请稍后再试');
            }
            try {
                $user = User::query()->select(['user_id', 'user_name', 'real_name', 'head_img', 'mobile', 'open_id'])
                    ->where(['open_id' => $data['openid']])->first();
                if (!$user) {
                    $user = User::query()->where(['union_id' => $data['unionid']])->first();
                    if ($user) {
                        ///   DB::connection('mysql_dinner')->table('user_index')->update(['wx_openid'=> $data['openid']]);
                        $user->open_id = $data['openid'];
                        $user->save();
                    } else {
                        $user = User::query()->create(
                            [
                                'open_id' => $data['openid'],
                                'union_id' => $data['unionid'] ?? '',
                                'head_img' => $param['image'] ?? null,
                                'salt' => ApiHelper::make_code(6),
                                'user_name' => $param['nickname'] ?? null
                            ]
                        );

                        /*   /////同步点餐系统
                           $userIndex = DB::connection('mysql_dinner')->table('user_index')->insert(
                               [
                                   'wx_openid' => $data['openid'],
                                   'unionid' => $data['unionid'] ?? '',
                                   'image' => $param['image'] ?? null,
                                   'nickname' => $param['nickname'] ?? null,
                                   'from_source' => $param['from_source'] ?? 0,
                               ]
                           );*/

                    }
                } else if (!$user->union_id) {
                    // DB::connection('mysql_dinner')->table('user_index')->update(['unionid'=> $data['union_id']]);
                    $user->union_id = $data['union_id'] ?? '';
                    $user->save();
                }
                $param = ['code' => $param['code'], 'image' => $param['image'], 'nickname' => $param['nickname']];
                $dinnerHost = $dinnerHost . 'auth/min_login';
                $dinnerData = ApiHelper::httpPost($dinnerHost, $param);
                $token = auth('api')->login($user);
            } catch (\Exception $exception) {
                Log::error('添加用户失败！', ['message' => $exception->getMessage(), 'data' => $param]);
                return ApiHelper::responseError($param, '授权失败请稍后再试！', CodeEnum::CODE_CHECK_AUTH);
            }

            $tokenData = $this->respondWithToken($token, $user->tel);
            return ApiHelper::backDataCheck(true, '查询成功！', ['school' => $tokenData, 'dinner' => $dinnerData]);
        }


        if (empty($param['mobile'])) {
            return ApiHelper::backDataCheck(false, '手机号码不存在能为空！');
        }
        $userRes = User::query()->select(['user_id', 'password', 'salt'])->where('mobile', $param['mobile'])->first();
        if (empty($userRes)) {
            return ApiHelper::backDataCheck(false, '手机号码不存在！');
        }
        if (empty($param['password'])) {
            return ApiHelper::backDataCheck(false, '密码不能为空！');
        }
        if (md5(md5($param['password'] . $userRes->salt)) === $userRes->password) {
            ////不能暴露密文需要重新查一次
            $userData = $userRes->select(['user_id', 'user_name', 'real_name', 'head_img', 'mobile', 'open_id', 'dinner_user_id'])
                ->where('user_id', $userRes->user_id)->first();
            $token = auth('api')->login($userData);
            $dinnerHost = $dinnerHost . 'auth/school_login';
            $dinnerData = ApiHelper::httpPost($dinnerHost, ['id' => $userData['dinner_user_id']]);
            $tokenData = $this->respondWithToken($token, $param['mobile']);
            return ApiHelper::backDataCheck(true, '查询成功！', ['school' => $tokenData, 'dinner' => $dinnerData ? json_decode($dinnerData) : $dinnerData]);
        } else {
            return ApiHelper::backDataCheck(false, '密码不正确！');
        }


        return ApiHelper::responseError($param, 'Bad Request！', CodeEnum::CODE_CHECK_AUTH);
    }

    /**
     * desc: 用户注册
     * auth: ckg
     * date: 2022/11/24 21:33
     * @param LoginRequest $request
     * @return JsonResponse
     */
    public function userRegister(LoginRequest $request): JsonResponse
    {
        try {
            $request->validate('reg');
        } catch (\Exception $e) {
            return ApiHelper::responseError([], $e->getMessage());
        }
        ////同步到点餐表
        $userIndex = DB::connection('mysql_dinner')->table('user_index')->insertGetId(
            [
                'tel' => $request->mobile
            ]
        );
        $salt = ApiHelper::make_code(9);
        $res = User::query()->create([
            'mobile' => $request->mobile,
            'salt' => $salt,
            'password' => md5(md5($request->password . $salt)),
            'card_no' => $request->card_no,
            'dinner_user_id' => $userIndex
        ]);

        return ApiHelper::backDataCheck((bool)$res, $res ? '注册成功' : '注册失败');
    }

    /**
     * desc:找回密码
     * auth: ckg
     * date: 2022/11/24 21:33
     * @param \App\Http\Requests\Auth\LoginRequest $request
     * @return JsonResponse
     */
    public function findPassword(LoginRequest $request): JsonResponse
    {
        try {
            $request->with('find')->validate('find');
        } catch (\Exception $e) {
            return ApiHelper::responseError([], $e->getMessage());
        }

        $user = User::query()->where(['card_no' => $request->card_no, 'mobile' => $request->mobile])->first();
        if (empty($user)) {
            return ApiHelper::backDataCheck(false, '手机号码和卡号不匹配！');
        }
        $res = $user->update(['password' => md5(md5($request->password . $user->salt))]);
        return ApiHelper::backDataCheck((bool)$res, $res ? '修改成功！' : '修改失败！');
    }

    /**
     * desc: 返回token数组
     * auth: ckg
     * date: 2022/11/24 21:33
     * @param $token
     * @param null $phone
     * @return array
     */
    public static function respondWithToken($token, $phone = null): array
    {

        $data = [
            'access_token' => $token,
            'token_type' => 'Bearer',
            'phone' => $phone,
            'expires_in' => 60000 //auth('Api')->factory()->getTTL() * 60,
        ];
        return $data;
        //
    }
}
